import { ConfigSingleton } from "../../../../../Core/Module/Config/ConfigSingleton";
import { IConfig } from "../../../../../Core/Module/Config/IConfig";
import { ProtoObject } from "../../../../../Core/Object/ProtoObject";
import { ConfigAttribute, GetTypeOf } from "../../../../../Decorator/Decorator";
import { List } from "../../../../../Support/Share/Lib/Collections/List";
import { Dictionary } from "../../../../../Support/Share/Lib/Dictionary";

@ConfigAttribute()
export class StartMachineConfigCategory extends ConfigSingleton<StartMachineConfigCategory> {
    private static _Instance: StartMachineConfigCategory;

    static get Instance(): StartMachineConfigCategory {
        return StartMachineConfigCategory._Instance;
    }

    protected set Instance(value: StartMachineConfigCategory) {
        StartMachineConfigCategory._Instance = value;
    }

    private dict: Dictionary<number, StartMachineConfig> = new Dictionary<number, StartMachineConfig>();
    private list: List<StartMachineConfig> = new List<StartMachineConfig>();

    Merge(o: Object): void {
        const s = o as StartMachineConfigCategory;
        this.list.AddRange(s.list);
    }

    MergeJson(o: Object): void {
        const s = o as { list: StartMachineConfig[] };
        const len = s.list.length;
        for (let i = 0; i < len; ++i) {
            const jsonObject = s.list[i];
            const config = StartMachineConfig.Create(jsonObject);
            this.list.Add(config);
        }
    }

    ProtoEndInit(): void {
        for (const key in this.list.ToArray()) {
            const index = parseInt(key);
            const config = this.list.Get(index);
            config.AfterEndInit();
            this.dict.Add(config.Id, config);
        }
        this.list.Clear();
        this.AfterEndInit();
    }

    Get(id: number): StartMachineConfig {
        const item = this.dict.TryGetValue(id);
        if (item == null) {
            throw new Error(`配置找不到，配置表名: ${GetTypeOf(StartMachineConfig)}，配置id: ${id}`);
        }
        return item;
    }

    Contain(id: number): boolean {
        return this.dict.ContainsKey(id);
    }

    GetAll(): Dictionary<number, StartMachineConfig> {
        return this.dict;
    }

    GetOne(): StartMachineConfig {
        if (this.dict == null || this.dict.Count <= 0) {
            return null;
        }
        return this.dict.Values().next().value;
    }
}

export class StartMachineConfig extends ProtoObject implements IConfig {
    static Create(o: Object): StartMachineConfig {
        const config = new StartMachineConfig();
        for (let key in o) {
            let oldKey = key;
            if (key === "_t") {
                continue;
            }
            if (key === "_Id" || key === "_id" || key === "id") {
                key = "Id";
            }
            config[key] = o[oldKey];
        }
        return config;
    }

    public Id: number;
    public InnerIP: string;
    public OuterIP: string;
    public WatcherPort: string;
}
